package com.lmaor.project.commons.annotation;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

import org.springframework.core.annotation.AnnotationUtils;


public class AnnotationExtendUtils {
	
	public static List<Annotation> getSuperAnnotation(Class<?extends Annotation> anns){
		List<Annotation> result = new ArrayList<Annotation>();
		List<Annotation> queue = Arrays.asList(anns.getAnnotations());
		for (int i = 0; i < queue.size(); i++) {
			Annotation ann = queue.get(i);
			if(!ann.getClass().getName().startsWith("java.lang")){
				queue.add(ann);
				Arrays.stream(ann.annotationType().getAnnotations())
				.filter(a->!a.getClass().getName().startsWith("java.lang"))
				.forEach(queue::add);
			}
		}
		return result;
	}
	public static Annotation getAnnotationByMethod(Class<?extends Annotation> annClass,Method method){
		Annotation[] anns = AnnotationUtils.getAnnotations(method);
		for (Annotation ann : anns) {
			if(ann.annotationType() == annClass || AnnotationUtils.isAnnotationMetaPresent(ann.annotationType(), annClass)){
				return ann;
			}
		}
		return null;
	}
	public static Annotation getAnnotationByBeanClass(Class<?extends Annotation> annClass,Class beanClass){
		
		LinkedList<Class> queue = new LinkedList<Class>();
		queue.addFirst(beanClass);
		while(!queue.isEmpty()){
			Class type = queue.removeFirst();
			Annotation anns[] = type.getAnnotations();
			for (Annotation ann : anns) {
				if(ann.annotationType() == annClass || AnnotationUtils.isAnnotationMetaPresent(ann.annotationType(), annClass)){
					return ann;
				}
			}
			Class superClass = type.getSuperclass();
			if(superClass!=Object.class){
				queue.addLast(superClass);
			}
			
		}
		
		return null;
	}
}
